#! /usr/bin/env python
# -*- coding: utf8 -*-
#
#  gitlab irc sender
#  Copyright (C) 2016-2017  Andrei Karas (4144)
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 3 of the License, or
#  any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.

from code.apihandler import ApiHandler
from code.configuration import Configuration
from code.core import Core
from code.logger import Logger
from code.messagehandler import MessageHandler
from code.project import ProjectClass
from code.serverhandler import ServerHandler

import logging
import unittest
import time


def init_log():
    Core.log = logging.getLogger('log')
    Core.log.setLevel(logging.INFO)
    log_handler = logging.handlers.RotatingFileHandler(
        "test.log",
        maxBytes = 100000000,
        backupCount = 1)
    f = logging.Formatter("%(asctime)s %(message)s",
        "%B %d %H:%M:%S")
    log_handler.setFormatter(f)
    Core.log.addHandler(log_handler)


class TestConfig1(unittest.TestCase):
    def setUp(self):
        global config
        config = Configuration()
        config.show_info = False
        config.loadConfiguration("test/config/config1.yaml")

    def tearDown(self):
        global config
        config = None

    def check_options_in(self, options):
        self.assertIn("show_commit_messages", options)
        self.assertIn("show_commits", options)
        self.assertIn("last_build_stage", options)

    def test_global(self):
        self.assertTrue(config.global_options.show_commits)
        self.assertEqual(config.global_options.listen_host, "127.0.0.1")
        self.assertEqual(config.global_options.listen_port, 8181)
        self.assertEqual(config.global_options.ii_server_directory, "irc.freenode.net")

    def test_projects(self):
        self.assertIn("/qqqqq/", config.projects)
        self.assertIn("/wwwwww/", config.projects)
        self.assertIsInstance(config.projects["/qqqqq/"], ProjectClass)
        self.assertIsInstance(config.projects["/wwwwww/"], ProjectClass)

    def test_actions(self):
        actions = config.projects["/qqqqq/"].actions
        self.assertIn("issue", actions)
        self.assertIn("push", actions)
        self.assertIn("tag_push", actions)
        self.assertIn("note", actions)
        self.assertIn("build", actions)
        self.assertIn("merge_request", actions)
        self.assertNotIn("show_commit_messages", actions)
        actions = config.projects["/wwwwww/"].actions
        self.assertIn("issue", actions)
        self.assertNotIn("build", actions)

    def test_channels(self):
        actions = config.projects["/qqqqq/"].actions
        self.assertEqual(actions["issue"], ["#channel1"])
        self.assertEqual(sorted(actions["push"]), sorted(["#channel1", "#channel2"]))
        self.assertEqual(actions["tag_push"], ["#channel1"])
        self.assertEqual(actions["note"], ["#channel1"])
        self.assertEqual(actions["build"], ["#channel1"])
        self.assertEqual(actions["merge_request"], ["#channel1"])
        actions = config.projects["/wwwwww/"].actions
        self.assertEqual(actions["issue"], ["#channel2"])

    def test_channels_order(self):
        actions = config.projects["/qqqqq/"].actions
        channels = actions["push"]
        it = iter(channels)
        channel = next(it)
        self.assertEqual(channel, "#channel1")
        channel = next(it)
        self.assertEqual(channel, "#channel2")

    def test_options_channels_list(self):
        options = config.projects["/qqqqq/"].channels
        self.assertIn("#channel1", options)
        self.assertIn("#channel2", options)
        options = config.projects["/wwwwww/"].channels
        self.assertIn("#channel2", options)

    def test_options_channels(self):
        options = config.projects["/qqqqq/"].channels
        chan = options["#channel1"]
        self.check_options_in(chan)
        self.assertTrue(chan.show_commit_messages)
        self.assertTrue(chan.show_commits)
        chan = options["#channel2"]
        self.check_options_in(chan)
        self.assertFalse(chan.show_commit_messages)
        self.assertTrue(chan.show_commits)
        options = config.projects["/wwwwww/"].channels
        chan = options["#channel2"]
        self.check_options_in(chan)
        self.assertTrue(chan.show_commit_messages)
        self.assertTrue(chan.show_commits)

    def test_options_project_properties(self):
        options = config.projects["/qqqqq/"].options
        self.assertEqual(options.ii_server_directory, "irc.freenode.net")
        self.assertEqual(options["ii_server_directory"], "irc.freenode.net")

    def test_default_service(self):
        self.assertEqual(config.global_options["service"], "gitlab")
        self.assertEqual(config.global_options.service, "gitlab")

    def test_service(self):
        options = config.projects["/qqqqq/"].options
        self.assertEqual(options["service"], "gitlab")
        self.assertEqual(options.service, "gitlab")


class ApiResponseMock():
    pass


class ApiHandlerMock(ApiHandler):
    def __init__(self):
        self.sent_requests = []
        self.mock_response = ApiResponseMock()
        self.mock_responses = []
        ApiHandler.__init__(self)

    def send_request(self, url, token, flag, cnt):
        self.sent_requests.append((url, token, flag, cnt))
        if len(self.mock_responses) == 0:
            return self.mock_response
        else:
            return self.mock_responses.pop()


class TestApiHandler(unittest.TestCase):
    def setUp(self):
        global apiHandler
#        Core.log = logging.getLogger('log')
        Core.config = Configuration()
        Core.config.loadDefaultOptions()
        Core.config.global_options.gitlab_api_token = "testapitoken"
        Configuration.irc_message_pause = 0
        apiHandler = ApiHandlerMock()

    def tearDown(self):
        global apiHandler
        apiHandler = None
#        Core.log = None
        Core.config = None

    def test_ApiHandler_add1(self):
        global apiHandler
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.add(("getlog", Core.config.global_options, 1, 2))
        self.assertEqual(len(apiHandler.requests), 1)
        self.assertEqual(apiHandler.requests[0], ("getlog", Core.config.global_options, 1, 2))

    def test_ApiHandler_add2(self):
        global apiHandler
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.add(("getlog", Core.config.global_options, 1, 2))
        apiHandler.add(("getlog2", Core.config.global_options, 2, 3))
        self.assertEqual(len(apiHandler.requests), 2)
        self.assertEqual(apiHandler.requests[0], ("getlog2", Core.config.global_options, 2, 3))
        self.assertEqual(apiHandler.requests[1], ("getlog", Core.config.global_options, 1, 2))

    def test_ApiHandler_check_retry_build_count(self):
        global apiHandler
        self.assertEqual(len(apiHandler.retry_builds), 0)
        Core.config.global_options.build_retry_count = 0
        self.assertEqual(apiHandler.check_retry_build_count("1", Core.config.global_options), False)
        apiHandler.retry_builds["100"] = 1;
        self.assertEqual(apiHandler.check_retry_build_count("100", Core.config.global_options), False)
        Core.config.global_options.build_retry_count = 1
        self.assertEqual(apiHandler.check_retry_build_count("100", Core.config.global_options), False)
        apiHandler.retry_builds["100"] = 3;
        Core.config.global_options.build_retry_count = 10
        self.assertEqual(apiHandler.check_retry_build_count("100", Core.config.global_options), True)
        apiHandler.retry_builds["100"] = 0;
        Core.config.global_options.build_retry_count = 2
        self.assertEqual(apiHandler.check_retry_build_count("100", Core.config.global_options), True)
        apiHandler.retry_builds["100"] = 1;
        self.assertEqual(apiHandler.check_retry_build_count("100", Core.config.global_options), True)
        apiHandler.retry_builds["100"] = 2;
        self.assertEqual(apiHandler.check_retry_build_count("100", Core.config.global_options), False)

    def test_ApiHandler_send_request1(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.send_request("http://qqqq", "12345", False, 10)
        self.assertEqual(len(apiHandler.requests), 0)
        self.assertEqual(apiHandler.sent_requests,
            [
                ("http://qqqq", "12345", False, 10)
            ])

    def test_ApiHandler_send_request2(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.send_request("http://qqqq", "12345", False, 10)
        apiHandler.send_request("http://www/test/url", "112233", True, 1)
        self.assertEqual(len(apiHandler.requests), 0)
        self.assertEqual(apiHandler.sent_requests,
            [
                ("http://qqqq", "12345", False, 10),
                ("http://www/test/url", "112233", True, 1)
            ])

    def test_ApiHandler_retry_build1(self):
        global apiHandler
        Core.config.global_options.build_retry_count = 1
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.retry_build(1, 2, "12345", Core.config.global_options)
        self.assertEqual(len(apiHandler.requests), 1)
        self.assertEqual(apiHandler.requests[0], ("getlog", Core.config.global_options, 1, 2, "12345"))
        apiHandler.retry_builds["12345"] = 1;
        apiHandler.retry_build(1, 2, "12345", Core.config.global_options)
        self.assertEqual(len(apiHandler.requests), 1)

    def test_ApiHandler_retry_build2(self):
        global apiHandler
        Core.config.global_options.build_retry_count = 2
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.retry_build(1, 2, "12345", Core.config.global_options)
        self.assertEqual(len(apiHandler.requests), 1)
        self.assertEqual(apiHandler.requests[0], ("getlog", Core.config.global_options, 1, 2, "12345"))
        apiHandler.retry_builds["12345"] = 1;
        apiHandler.retry_build(1, 2, "12345", Core.config.global_options)
        self.assertEqual(len(apiHandler.requests), 2)
        self.assertEqual(apiHandler.requests[0], ("getlog", Core.config.global_options, 1, 2, "12345"))
        self.assertEqual(apiHandler.requests[1], ("getlog", Core.config.global_options, 1, 2, "12345"))

    def test_ApiHandler_request_build_log(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.request_build_log(12, 34, Core.config.global_options)
        self.assertEqual(len(apiHandler.requests), 0)
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3)
            ])

    def test_ApiHandler_request_build_retry1(self):
        global apiHandler
        Core.config.global_options.build_retry_count = 1
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.request_build_retry(12, 34, "12345", Core.config.global_options)
        self.assertEqual(len(apiHandler.requests), 0)
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])

    def test_ApiHandler_request_build_retry2(self):
        global apiHandler
        Core.config.global_options.build_retry_count = 1
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.request_build_retry(12, 34, "12345", Core.config.global_options)
        self.assertEqual(len(apiHandler.requests), 0)
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        apiHandler.sent_requests = []
        apiHandler.request_build_retry(12, 34, "12345", Core.config.global_options)
        self.assertEqual(len(apiHandler.requests), 0)
        self.assertEqual(len(apiHandler.sent_requests), 0)

    def test_ApiHandler_request_build_retry3(self):
        global apiHandler
        Core.config.global_options.build_retry_count = 2
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.request_build_retry(12, 34, "12345", Core.config.global_options)
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.request_build_retry(12, 34, "12345", Core.config.global_options)
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.sent_requests = []
        apiHandler.request_build_retry(12, 34, "12345", Core.config.global_options)
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command1(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = "normal response text\nERROR: Job failed"
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command2(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = "normal response text\n[31;1mERROR: Build failed (system failure): some kind of error"
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command3(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = "runner header\n[0;m[0KUsing Shell executor...\n[0;mNo passwd entry for user 'gitlab-runner'\n"
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command4(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = "runner header\nsome test here\n\n\n[31;1mFATAL: invalid argument                           [0;m \n[31;1mERROR: Build failed: exit code 1\n[0;m"
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command5(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = "runner header\nremote: GitLab is not responding\nfatal: unable to access 'https://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@gitlab.com/"
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command6(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = "runner header\n[31;1mFATAL: invalid argument                           [0;m \n[31;1mERROR: Job failed: exit code 1\n[0;m"
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command7(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = ""
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command8(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = "runner header\n[31;1mERROR: Job failed (system failure):"
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command9(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = "runner header\n[31;1mERROR: Job failed: canceled\n[0;m"
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command10(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = "runner header\nsome text\nsome text"
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command11(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = "Cloning into '/jobs/simplepackagemanager/spm'...\n" + \
            "fatal: unable to access 'https://gitlab-ci-token:xxxxxxxxxxxxxxxxxxxx@" + \
            "gitlab.com/simplepackagemanager/spm.git/': The requested URL returned error: 500\n" + \
            "/bin/bash: line 50: cd: /jobs/simplepackagemanager/spm: No such file or directory\n"
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command12(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = "some text here\n" + \
            "[32;1mUploading artifacts...[0;m\n" + \
            "logs: found 39 matching files                     [0;m \n" + \
            "[31;1mERROR: Uploading artifacts to coordinator... error" + \
            "[0;m  [31;1merror[0;m=couldn't execute POST against " + \
            "https://gitlab.com/api/v4/jobs/12345667/artifacts?expire_in=3+week: " + \
            "Post https://gitlab.com/api/v4/jobs/12345678/artifacts?expire_in=3+week: " + \
            "EOF [31;1mid[0;m=32838039 [31;1mtoken[0;m=zzz1_-aa\n" + \
            "[0;33mWARNING: Retrying...                              " + \
            "[0;m \n" + \
            "[31;1mERROR: Uploading artifacts to coordinator... error" + \
            "[0;m  [31;1merror[0;m=couldn't execute POST against " + \
            "https://gitlab.com/api/v4/jobs/12345678/artifacts?expire_in=3+week: " + \
            "Post https://gitlab.com/api/v4/jobs/12345678/artifacts?expire_in=3+week: " + \
            "dial tcp 52.167.219.168:443: getsockopt: connection refused " + \
            "[31;1mid[0;m=32838039 [31;1mtoken[0;m=zzz1_-aa\n" + \
            "[31;1mFATAL: invalid argument                           " + \
            "[0;m \n" + \
            "[31;1mERROR: Job failed: exit code 1\n" + \
            "[0;m\n"
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command13(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = \
            "some text here\n" + \
            "[32;1mUploading artifacts...[0;m\n" + \
            "logs: found 3 matching files                      [0;m \n" + \
            "[31;1mERROR: Uploading artifacts to coordinator... error" + \
            "[0;m  [31;1merror[0;m=couldn't execute POST against " + \
            "https://gitlab.com/api/v4/jobs/34276002/artifacts?expire_in=3+week: " + \
            "Post https://gitlab.com/api/v4/jobs/34276002/artifacts?expire_in=3+week: " + \
            "dial tcp: i/o timeout [31;1mid[0;m=34276002 [31;1mtoken[0;m=vpZsbcy8\n" + \
            "[0;33mWARNING: Retrying...                              " + \
            "[0;m \n" + \
            "[31;1mERROR: Uploading artifacts to coordinator... error" + \
            "[0;m  [31;1merror[0;m=couldn't execute POST against " + \
            "https://gitlab.com/api/v4/jobs/34276002/artifacts?expire_in=3+week: " + \
            "Post https://gitlab.com/api/v4/jobs/34276002/artifacts?expire_in=3+week: " + \
            "dial tcp: i/o timeout [31;1mid[0;m=34276002 [31;1mtoken[0;m=vpZsbcy8\n" + \
            "[0;33mWARNING: Retrying...                              " + \
            "[0;m \n" + \
            "[31;1mERROR: Uploading artifacts to coordinator... error" + \
            "[0;m  [31;1merror[0;m=couldn't execute POST against " + \
            "https://gitlab.com/api/v4/jobs/34276002/artifacts?expire_in=3+week: " + \
            "Post https://gitlab.com/api/v4/jobs/34276002/artifacts?expire_in=3+week: " + \
            "dial tcp: i/o timeout [31;1mid[0;m=34276002 [31;1mtoken[0;m=vpZsbcy8\n" + \
            "[31;1mFATAL: invalid argument                           " + \
            "[0;m \n" + \
            "[31;1mERROR: Job failed: exit status 1\n" + \
            "[0;m\n"

        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command14(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = """section_end:1509362288:build_script[0Ksection_start:1509362288:after_script[0Ksection_end:1509362288:after_script[0Ksection_start:1509362288:upload_artifacts[0Ksection_end:1509362288:upload_artifacts[0K[31;1mERROR: Job failed: exit code 137
[0;m
"""
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command15(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = """[0;m[0KPulling docker image debian:unstable ...
[0;m[31;1mERROR: Preparation failed: Error: No such image: debian:unstable
[0;m[32;1mWill be retried in 3s ...
[0;m[31;1mERROR: Job failed (system failure): Error: No such image: debian:unstable
[0;m"""
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command16(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = """bin: found 18 matching files                      [0;m 
[0;33mWARNING: Uploading artifacts to coordinator... failed[0;m  [0;33mid[0;m=44715830 [0;33mresponseStatus[0;m=500 Server Error [0;33mstatus[0;m=500 Server Error [0;33mtoken[0;m=xDVuvywY
[0;33mWARNING: Retrying...                              [0;m 
[0;33mWARNING: Uploading artifacts to coordinator... failed[0;m  [0;33mid[0;m=44715830 [0;33mresponseStatus[0;m=500 Server Error [0;33mstatus[0;m=500 Server Error [0;33mtoken[0;m=xDVuvywY
[0;33mWARNING: Retrying...                              [0;m 
[0;33mWARNING: Uploading artifacts to coordinator... failed[0;m  [0;33mid[0;m=44715830 [0;33mresponseStatus[0;m=500 Server Error [0;33mstatus[0;m=500 Server Error [0;33mtoken[0;m=xDVuvywY
[31;1mFATAL: invalid argument                           [0;m 
section_end:1513334209:upload_artifacts[0K[31;1mERROR: Job failed: exit code 1
[0;m
"""
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command17(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = """section_end:1526049500:build_script[0Ksection_start:1526049500:after_script[0Ksection_end:1526049500:after_script[0Ksection_start:1526049500:upload_artifacts[0Ksection_end:1526049500:upload_artifacts[0K[31;1mERROR: Job failed: execution took longer than 3h0m0s seconds
[0;m"""
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)

    def test_ApiHandler_parse_command18(self):
        global apiHandler
        self.assertEqual(len(apiHandler.sent_requests), 0)
        self.assertEqual(len(apiHandler.requests), 0)
        apiHandler.mock_response.text = """ ...
[0;m[0KPulling docker image debian:unstable ...
[0;m[31;1mERROR: Job failed: Error response from daemon: error parsing HTTP 404 response body: invalid character 'p' after top-level value: "404 page not found\n" (executor_docker.go:168:0s)
[0;m
"""
        apiHandler.parse_command(("getlog", Core.config.global_options, 12, 34, "12345"))
        self.assertEqual(apiHandler.sent_requests,
            [
                ('https://gitlab.com/api/v4/projects/12/jobs/34/trace', 'testapitoken', False, 3),
                ('https://gitlab.com/api/v4/projects/12/jobs/34/retry', 'testapitoken', True, 3)
            ])
        self.assertEqual(len(apiHandler.requests), 0)


class TestMessageHandler(unittest.TestCase):
    def setUp(self):
        Core.config = Configuration()
        Core.config.loadDefaultOptions()
        Core.config.global_options.ii_server_directory = "test/channels"
        Configuration.irc_message_pause = 0
        global messageHandler
        messageHandler = MessageHandler()

    def tearDown(self):
        global messageHandler
        messageHandler = None
        Core.config = None

    def test_MessageHandler_add(self):
        global messageHandler
        self.assertEqual(len(messageHandler.messages), 0)
        messageHandler.add("channel1", "this is message 1")
        self.assertEqual(len(messageHandler.messages), 1)
        self.assertEqual(messageHandler.messages[0], ("channel1", "this is message 1"))

    def test_MessageHandler_add2(self):
        global messageHandler
        self.assertEqual(len(messageHandler.messages), 0)
        messageHandler.add("channel1", "this is message 1")
        self.assertEqual(len(messageHandler.messages), 1)
        messageHandler.add("channel2", "this is message 2")
        self.assertEqual(len(messageHandler.messages), 2)
        self.assertEqual(messageHandler.messages[0], ("channel2", "this is message 2"))
        self.assertEqual(messageHandler.messages[1], ("channel1", "this is message 1"))

    def test_MessageHandler_split1(self):
        global messageHandler
        self.assertEqual(len(messageHandler.messages), 0)
        parts = messageHandler.split("channel1",
            "this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message ")
        self.assertEqual(parts,
            [
                ('channel1', 'this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message')
            ])

    def test_MessageHandler_split2(self):
        global messageHandler
        self.assertEqual(len(messageHandler.messages), 0)
        parts = messageHandler.split("channel1",
            "this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message ")
        self.assertEqual(parts,
            [
                ('channel1', 'this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this is message long message this'),
                ('channel1', 'is message long message this is message long message this is message long message this is message long message this is message long message this is message long message')
            ])

    def test_run1(self):
        messageHandler.start()
        time.sleep(1)
        self.assertEqual(messageHandler.isAlive(), True)
        messageHandler.die = True
        time.sleep(1)
        self.assertEqual(messageHandler.isAlive(), False)

    def test_run2(self):
        messageHandler.start()
        messageHandler.add("channel1", "this is message")
        self.assertEqual(messageHandler.isAlive(), True)
        time.sleep(1)
        self.assertEqual(messageHandler.isAlive(), True)
        messageHandler.die = True
        messageHandler.join()
        self.assertEqual(messageHandler.isAlive(), False)
        with open(Core.config.global_options.ii_server_directory + "/channel1/in", "r") as r:
            text = r.read()
        self.assertEqual(text, "this is message\n")


class MessageHandlerMock(MessageHandler):
    def start(self):
        pass

class SocketMock():
    def __init__(self):
        self.time = 0

    def settimeout(self, time):
        self.time = time

class WFileMock():
    def __init__(self):
        self.closed = False
        self.data = None

    def close(self):
        self.closed = True

    def write(self, data):
        self.data = data

    def flush(self):
        pass

class RFileMock():
    def __init__(self):
        self._sock = SocketMock()
        self.data = ""
        self.closed = False

    def read(self, size):
        return self.data[:size]

    def close(self):
        self.closed = True

    def flush(self):
        pass

    def readline(self, size):
        return ""

class ServerHandlerMock(ServerHandler):
    def __init__(self, *args):
        self.response_code = 0
        self.headers_compleate = False
        self.send_headers_complete = False
        self.wfile = WFileMock()
        self.rfile = RFileMock()
        self.headers = dict()
        self.send_headers = dict()
        self.serverData = ""
        ServerHandler.__init__(self, *args)

    def send_response(self, code):
        self.response_code = code

    def end_headers(self):
        self.headers_compleate = True
        self.send_headers_complete = True

    def addData(self, data):
        self.headers["Content-Length"] = len(data)
        self.rfile.data = self.fromStr(data)

    def addDataFile(self, name):
        with open(name, "r") as r:
            data = r.read()
            self.addData(data)

    def send_header(self, name, value):
        self.send_headers[name] = value

    def setup(self):
        pass

    def handle(self):
        pass

class RequestMock:
    def makefile(self, mode, size):
        return RFileMock()

class TestServerHandler(unittest.TestCase):
    def setUp(self):
        Core.config = Configuration()
        Core.config.show_info = False
        Core.server = ServerHandlerMock(RequestMock(), ("127.0.0.1", 123), None)
        Core.messageHandler = MessageHandlerMock()
        Core.apiHandler = ApiHandlerMock()
#        Core.log = logging.getLogger('log')

    def tearDown(self):
        Core.config = None
        Core.server = None
        Core.messageHandler = None
        Core.apiHandler = None
#        Core.log = None

    def run_post(self, configName, path, data, retCode):
        Core.config.loadConfiguration(configName)
        Core.server.path = path
        Core.server.addDataFile(data)
        Core.server.do_POST()
        self.assertEqual(Core.server.response_code, retCode)
        self.assertTrue(Core.server.send_headers_complete)

    def run_post_github(self, configName, path, data, object_kind, retCode):
        Core.config.loadConfiguration(configName)
        Core.server.path = path
        Core.server.addDataFile(data)
        Core.server.headers["X-GitHub-Event"] = object_kind
        Core.server.do_POST()
        self.assertEqual(Core.server.response_code, retCode)
        self.assertTrue(Core.server.send_headers_complete)

    def test_get(self):
        Core.config.loadConfiguration("test/config/config1.yaml")
        Core.server.do_GET()
        self.assertEqual(Core.server.response_code, 400)
        self.assertTrue(Core.server.send_headers_complete)
        self.assertTrue(Core.server.wfile.closed)

    def test_head(self):
        Core.config.loadConfiguration("test/config/config1.yaml")
        Core.server.do_HEAD()
        self.assertEqual(Core.server.response_code, 400)
        self.assertTrue(Core.server.send_headers_complete)
        self.assertTrue(Core.server.wfile.closed)

    def test_post_error1(self):
        Core.config.loadConfiguration("test/config/config1.yaml")
        Core.server.path = "/"
        Core.server.addData("{ \"test\": 1 }")
        Core.server.do_POST()
        self.assertEqual(Core.server.response_code, 400)
        self.assertTrue(Core.server.send_headers_complete)
        self.assertTrue(Core.server.wfile.closed)

    def test_post_error2(self):
        self.run_post("test/config/post1.yaml", "/qqqqq1/", "test/json/push.json", 400)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_error3(self):
        self.run_post("test/config/post_no_error.yaml", "/qqqqq1/", "test/json/push.json", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_error4(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/push_wrong_project.json", 400)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_push(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/push.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel1', 'This reverts commit 9263c57209c2eda23e963d01862a5ded14832fff.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel1', 'and here second line'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5')
            ])

    def test_post_push2(self):
        self.run_post("test/config/post3.yaml", "/qqqqq/", "test/json/push.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel1', 'This reverts commit 9263c57209c2eda23e963d01862a5ded14832fff.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel1', 'and here second line'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5')
            ])

    def test_post_push3(self):
        self.run_post("test/config/post3.yaml", "/aaaa/bbb/", "test/json/push.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.messageHandler.messages), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)

    def test_post_push4(self):
        self.run_post("test/config/post4.yaml", "/aaaa/bbb/", "test/json/issue_opened.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel4', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f opened issue \x0303#4\x0f: test issue 3 https://gitlab.com/4144/hooktest/issues/4'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f opened issue \x0303#4\x0f: test issue 3 https://gitlab.com/4144/hooktest/issues/4')
            ])

    def test_post_push_first1(self):
        self.run_post("test/config/post4.yaml", "/qqqqq/", "test/json/push_first.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303d5810b8\x0f - Add some more error checks and escapes.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303508999b\x0f - Add error checks into common.sh'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03032ddf896\x0f - Add common_run_package into clean and updatesrc scripts.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303e264276\x0f - Add libxml2 package.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303b1506f0\x0f - Add curl package.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x030300ad444\x0f - Fix MANPATH variable in generated environments.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03038478b62\x0f - Add libpng package.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303d356bd7\x0f - Create env, bin, tmp directories if it not exists.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x030365ddf15\x0f - Initial commit.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 9 commits \x0303master\x0f https://gitlab.com/simplepackagemanager/hooktest/commits/d5810b8'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303d5810b8\x0f - Add some more error checks and escapes.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303508999b\x0f - Add error checks into common.sh'),
                ('#channel1', 'This allow override function from package script.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03032ddf896\x0f - Add common_run_package into clean and updatesrc scripts.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303e264276\x0f - Add libxml2 package.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303b1506f0\x0f - Add curl package.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x030300ad444\x0f - Fix MANPATH variable in generated environments.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03038478b62\x0f - Add libpng package.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303d356bd7\x0f - Create env, bin, tmp directories if it not exists.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x030365ddf15\x0f - Initial commit.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 9 commits \x0303master\x0f https://gitlab.com/simplepackagemanager/hooktest/commits/d5810b8')
            ])

    def test_post_push_first2(self):
        self.run_post("test/config/post5.yaml", "/qqqqq/", "test/json/push_first.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x030365ddf15\x0f - Initial commit.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303d356bd7\x0f - Create env, bin, tmp directories if it not exists.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03038478b62\x0f - Add libpng package.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x030300ad444\x0f - Fix MANPATH variable in generated environments.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303b1506f0\x0f - Add curl package.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303e264276\x0f - Add libxml2 package.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03032ddf896\x0f - Add common_run_package into clean and updatesrc scripts.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303508999b\x0f - Add error checks into common.sh'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303d5810b8\x0f - Add some more error checks and escapes.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 9 commits \x0303master\x0f https://gitlab.com/simplepackagemanager/hooktest/commits/d5810b8'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303d5810b8\x0f - Add some more error checks and escapes.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303508999b\x0f - Add error checks into common.sh'),
                ('#channel1', 'This allow override function from package script.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03032ddf896\x0f - Add common_run_package into clean and updatesrc scripts.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303e264276\x0f - Add libxml2 package.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303b1506f0\x0f - Add curl package.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x030300ad444\x0f - Fix MANPATH variable in generated environments.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03038478b62\x0f - Add libpng package.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303d356bd7\x0f - Create env, bin, tmp directories if it not exists.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x030365ddf15\x0f - Initial commit.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 9 commits \x0303master\x0f https://gitlab.com/simplepackagemanager/hooktest/commits/d5810b8')
            ])


    def test_post_push_new_branch(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/push_new_branch.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f created/changed branch \x0303branch3\x0f on commit \x0303ec86559\x0f https://gitlab.com/4144/hooktest/commits/branch3'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f created/changed branch \x0303branch3\x0f on commit \x0303ec86559\x0f https://gitlab.com/4144/hooktest/commits/branch3')
            ])

    def test_post_push_delete_branch(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/push_delete_branch.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f deleted branch \x0303branch3\x0f'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f deleted branch \x0303branch3\x0f')
            ])

    def test_post_tag_push(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/tag_push.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed tag \x0303testtag1\x0f on commit \x0303a63cb84\x0f https://gitlab.com/4144/hooktest/commit/a63cb84'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed tag \x0303testtag1\x0f on commit \x0303a63cb84\x0f https://gitlab.com/4144/hooktest/commit/a63cb84')
            ])

    def test_post_tag_push_delete(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/tag_push_delete.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f deleted tag \x0303testtag1\x0f'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f deleted tag \x0303testtag1\x0f')
            ])

    def test_post_note_commit(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/note_commit.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f add note on commit \x03039485388\x0f https://gitlab.com/4144/hooktest/commit/9485388#note_4860635'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f add note on commit \x03039485388\x0f https://gitlab.com/4144/hooktest/commit/9485388#note_4860635')
            ])

    def test_post_note_merge_request(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/note_merge_request.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f add note into merge request \x0303!5\x0f (\x03034144testgroup:master\x0f to \x0303master\x0f) https://gitlab.com/4144/hooktest/merge_requests/5#note_4860679'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f add note into merge request \x0303!5\x0f (\x03034144testgroup:master\x0f to \x0303master\x0f) https://gitlab.com/4144/hooktest/merge_requests/5#note_4860679')
            ])

    def test_post_note_issue(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/note_issue.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f add note into issue \x0303#2\x0f https://gitlab.com/4144/hooktest/issues/2#note_4860707'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f add note into issue \x0303#2\x0f https://gitlab.com/4144/hooktest/issues/2#note_4860707')
            ])

    def test_post_note_snippet(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/note_snippet.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f add note into snippet \x0303$17880\x0f https://gitlab.com/4144/hooktest/snippets/17880#note_4860729'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f add note into snippet \x0303$17880\x0f https://gitlab.com/4144/hooktest/snippets/17880#note_4860729')
            ])

    def test_post_build_pending1(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/build_pending.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_build_pending2(self):
        self.run_post("test/config/post8.yaml", "/qqqqq/", "test/json/build_pending.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_build_failed1(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/build_failed.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126'),
                ('#channel1', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126')
            ])

    def test_post_build_failed2(self):
        self.run_post("test/config/post6.yaml", "/qqqqq/", "test/json/build_failed.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126'),
                ('#channel1', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126')
            ])

    def test_post_build_failed3(self):
        self.run_post("test/config/post6.yaml", "/qqqqq2/", "test/json/build_failed.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126')
            ])

    def test_post_build_failed_custom(self):
        self.run_post("test/config/post_build_fail_custom.yaml", "/qqqqq/", "test/json/build_failed.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', 'fail for all'),
                ('#channel3', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126'),
                ('#channel1', 'fail for channel 1'),
                ('#channel1', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126')
            ])

    def test_post_build_failed_ignore(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/build_failed_allow_failure.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.messageHandler.messages), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)

    def test_post_build_failed_allow_failure(self):
        self.run_post("test/config/post2.yaml", "/qqqqq/", "test/json/build_failed_allow_failure.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel1', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126')
            ])

    def test_post_build_failed_retry1(self):
        self.run_post("test/config/post7.yaml", "/qqqqq/", "test/json/build_failed.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126'),
                ('#channel1', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126')
            ])
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(Core.apiHandler.requests,
            [
                ('getlog', Core.config.projects["/qqqqq/"].options, 211275, 1102126, "724883eed1db5e2cb097058fa16d67def6c031b9")
            ])
        Core.apiHandler.retry_builds["724883eed1db5e2cb097058fa16d67def6c031b9"] = 1
        self.run_post("test/config/post7.yaml", "/qqqqq/", "test/json/build_failed.json", 200)
        self.assertEqual(Core.apiHandler.requests,
            [
                ('getlog', Core.config.projects["/qqqqq/"].options, 211275, 1102126, "724883eed1db5e2cb097058fa16d67def6c031b9"),
                ('getlog', Core.config.projects["/qqqqq/"].options, 211275, 1102126, "724883eed1db5e2cb097058fa16d67def6c031b9")
            ])

    def test_post_build_failed_retry2(self):
        Core.apiHandler.retry_builds["724883eed1db5e2cb097058fa16d67def6c031b9"] = 1
        self.run_post("test/config/post8.yaml", "/qqqqq/", "test/json/build_failed.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126'),
                ('#channel1', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126')
            ])
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)

    def test_post_build_fail_final(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/build_success2.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] Build \x0307#13419990\x0f for commit \x030332c9cf6\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/13419990'),
                ('#channel1', '[\x0302hooktest\x0f] Build \x0307#13419990\x0f for commit \x030332c9cf6\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/13419990')
            ])

    def test_post_build_fail_allowed_to_fail1(self):
        self.run_post("test/config/post10.yaml", "/qqqqq2/", "test/json/build_failed.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_build_fail_allowed_to_fail2(self):
        self.run_post("test/config/post11.yaml", "/qqqqq2/", "test/json/build_failed.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] Build \x0307#1102126 pages\x0f for commit \x0303724883e\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/builds/1102126')
            ])

    def test_post_build_success_final(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/build_success.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] Build \x0307#1102130\x0f for commit \x0303724883e\x0f from \x0303master\x0f success https://gitlab.com/4144/hooktest/builds/1102130'),
                ('#channel1', '[\x0302hooktest\x0f] Build \x0307#1102130\x0f for commit \x0303724883e\x0f from \x0303master\x0f success https://gitlab.com/4144/hooktest/builds/1102130')
            ])

    def test_post_build_success_allow_fail(self):
        self.run_post("test/config/post6.yaml", "/qqqqq2/", "test/json/build_success3.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_build_success_allow_fail2(self):
        self.run_post("test/config/post10.yaml", "/qqqqq2/", "test/json/build_success3.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel1', '[\x0302hooktest\x0f] Build \x0307#13419986\x0f for commit \x030332c9cf6\x0f from \x0303master\x0f success https://gitlab.com/4144/hooktest/builds/13419986')
            ])

    def test_post_build_success_skipped(self):
        self.run_post("test/config/post2.yaml", "/qqqqq/", "test/json/build_success.json", 200)
        self.assertEqual(len(Core.apiHandler.sent_requests), 0)
        self.assertEqual(len(Core.messageHandler.messages), 0)
        self.assertEqual(len(Core.apiHandler.requests), 0)

    def test_post_pipeline_success1(self):
        self.run_post("test/config/post2.yaml", "/qqqqq/", "test/json/pipeline_success1.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] Pipeline \x0307#4012845\x0f for commit \x0303704fb18\x0f from \x0303master\x0f success https://gitlab.com/4144/hooktest/pipelines/4012845'),
                ('#channel1', '[\x0302hooktest\x0f] Pipeline \x0307#4012845\x0f for commit \x0303704fb18\x0f from \x0303master\x0f success https://gitlab.com/4144/hooktest/pipelines/4012845')
            ])

    def test_post_pipeline_success2(self):
        self.run_post("test/config/post12.yaml", "/qqqqq/", "test/json/pipeline_success1.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
            ])

    def test_post_pipeline_success_bad(self):
        self.run_post("test/config/post2.yaml", "/qqqqq/", "test/json/pipeline_success2.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] Pipeline \x0307#4012845\x0f for commit \x0303704fb18\x0f from \x0303master\x0f success https://gitlab.com/4144/hooktest/pipelines/4012845'),
                ('#channel1', '[\x0302hooktest\x0f] Pipeline \x0307#4012845\x0f for commit \x0303704fb18\x0f from \x0303master\x0f success https://gitlab.com/4144/hooktest/pipelines/4012845')
            ])

    def test_post_pipeline_failed1(self):
        self.run_post("test/config/post2.yaml", "/qqqqq/", "test/json/pipeline_failed1.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] Pipeline \x0307#4013166\x0f for commit \x030345d66ca\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/pipelines/4013166'),
                ('#channel1', '[\x0302hooktest\x0f] Pipeline \x0307#4013166\x0f for commit \x030345d66ca\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/pipelines/4013166')
            ])

    def test_post_pipeline_failed2(self):
        self.run_post("test/config/post6.yaml", "/qqqqq/", "test/json/pipeline_failed1.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] Pipeline \x0307#4013166\x0f for commit \x030345d66ca\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/pipelines/4013166'),
                ('#channel1', 'pipeline failed message'),
                ('#channel1', '[\x0302hooktest\x0f] Pipeline \x0307#4013166\x0f for commit \x030345d66ca\x0f from \x0303master\x0f failed https://gitlab.com/4144/hooktest/pipelines/4013166')
            ])

    def test_post_pipeline_failed3(self):
        self.run_post("test/config/post9.yaml", "/qqqqq/", "test/json/pipeline_failed1.json", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_pipeline_failed_bad(self):
        self.run_post("test/config/post2.yaml", "/qqqqq/", "test/json/pipeline_failed2.json", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_merge_request_merged(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/merge_request_merged.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f merged merge request \x0303!5\x0f: test9 https://gitlab.com/4144/hooktest/merge_requests/5'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f merged merge request \x0303!5\x0f: test9 https://gitlab.com/4144/hooktest/merge_requests/5')
            ])

    def test_post_merge_request_opened(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/merge_request_opened.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f opened merge request \x0303!6\x0f: Merge branch \'master\' into \'branch2\' https://gitlab.com/4144/hooktest/merge_requests/6'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f opened merge request \x0303!6\x0f: Merge branch \'master\' into \'branch2\' https://gitlab.com/4144/hooktest/merge_requests/6')
            ])

    def test_post_merge_request_closed(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/merge_request_closed.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f closed merge request \x0303!6\x0f: Merge branch \'master\' into \'branch2\' https://gitlab.com/4144/hooktest/merge_requests/6'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f closed merge request \x0303!6\x0f: Merge branch \'master\' into \'branch2\' https://gitlab.com/4144/hooktest/merge_requests/6')
            ])

    def test_post_merge_request_reopened(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/merge_request_reopened.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f reopened merge request \x0303!6\x0f: Merge branch \'master\' into \'branch2\' https://gitlab.com/4144/hooktest/merge_requests/6'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f reopened merge request \x0303!6\x0f: Merge branch \'master\' into \'branch2\' https://gitlab.com/4144/hooktest/merge_requests/6')
            ])

    def test_post_merge_request_updated(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/merge_request_updated.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f updated merge request \x0303!6\x0f: normal mr title https://gitlab.com/4144/hooktest/merge_requests/6'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f updated merge request \x0303!6\x0f: normal mr title https://gitlab.com/4144/hooktest/merge_requests/6')
            ])

    def test_post_issue_opened(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/issue_opened.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f opened issue \x0303#4\x0f: test issue 3 https://gitlab.com/4144/hooktest/issues/4'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f opened issue \x0303#4\x0f: test issue 3 https://gitlab.com/4144/hooktest/issues/4')
            ])

    def test_post_issue_closed(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/issue_closed.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f closed issue \x0303#4\x0f: test issue 3 https://gitlab.com/4144/hooktest/issues/4'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f closed issue \x0303#4\x0f: test issue 3 https://gitlab.com/4144/hooktest/issues/4')
            ])

    def test_post_issue_reopened(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/issue_reopened.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f reopened issue \x0303#4\x0f: test issue 3 https://gitlab.com/4144/hooktest/issues/4'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f reopened issue \x0303#4\x0f: test issue 3 https://gitlab.com/4144/hooktest/issues/4')
            ])

    def test_post_issue_updated(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/issue_updated.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel3', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f updated issue \x0303#4\x0f: test issue 3 https://gitlab.com/4144/hooktest/issues/4'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f updated issue \x0303#4\x0f: test issue 3 https://gitlab.com/4144/hooktest/issues/4')
            ])

    def test_post_push_long(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/push_long.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03032371057\x0f - very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line.'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 1 commits \x0303master\x0f https://gitlab.com/4144/hooktest/commit/2371057'),
                ('#channel1', '123456789 123456789 123456789 aaaaa'),
                ('#channel1', '123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03032371057\x0f - very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line. very long line.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 1 commits \x0303master\x0f https://gitlab.com/4144/hooktest/commit/2371057')
            ])

    def test_post_push_no_commits(self):
        self.run_post("test/config/post_no_commits.yaml", "/qqqqq/", "test/json/push.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel1', 'This reverts commit 9263c57209c2eda23e963d01862a5ded14832fff.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel1', 'and here second line'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5')
            ])

    def test_post_push_lines1(self):
        self.run_post("test/config/post1.yaml", "/qqqqq/", "test/json/push_lines.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel1', 'This reverts commit 9263c57209c2eda23e963d01862a5ded14832fff.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel1', 'line 3'),
                ('#channel1', 'and here second line'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5')
            ])

    def test_post_push_lines2(self):
        self.run_post("test/config/post_lines1.yaml", "/qqqqq/", "test/json/push_lines.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel1', 'This reverts commit 9263c57209c2eda23e963d01862a5ded14832fff.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5')
            ])

    def test_post_push_lines3(self):
        self.run_post("test/config/post_lines2.yaml", "/qqqqq/", "test/json/push_lines.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel1', 'This reverts commit 9263c57209c2eda23e963d01862a5ded14832fff.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel1', 'line 4'),
                ('#channel1', 'line 3'),
                ('#channel1', 'and here second line'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5')
            ])

    def test_post_push_branches_deny1(self):
        self.run_post("test/config/post_branches_deny1.yaml", "/qqqqq/", "test/json/push.json", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_push_branches_deny2(self):
        self.run_post("test/config/post_branches_deny2.yaml", "/qqqqq/", "test/json/push.json", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_push_branches_allow1(self):
        self.run_post("test/config/post_branches_allow1.yaml", "/qqqqq/", "test/json/push.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel1', 'This reverts commit 9263c57209c2eda23e963d01862a5ded14832fff.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel1', 'and here second line'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5')
            ])

    def test_post_push_branches_allow2(self):
        self.run_post("test/config/post_branches_allow2.yaml", "/qqqqq/", "test/json/push.json", 200)
        self.assertEqual(Core.messageHandler.messages,
            [
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel2', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039263c57\x0f - failing build'),
                ('#channel1', 'This reverts commit 9263c57209c2eda23e963d01862a5ded14832fff.'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x03039485388\x0f - Revert "failing build"'),
                ('#channel1', 'and here second line'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f \x0303ec86559\x0f - update from web'),
                ('#channel1', '[\x0302hooktest\x0f] \x0307Andrei Karas\x0f pushed 3 commits \x0303master\x0f https://gitlab.com/4144/hooktest/compare/1234c5...9263c5')
            ])

    def test_create_instance(self):
        handler = ServerHandler(RequestMock(), ("127.0.0.1", 123), None)
        self.assertEqual(handler.version_string(), "nginx")
        handler.log_message("test")
        handler = None

    def test_post_codeship_build_error1(self):
        self.run_post("test/config/codeship1.yaml", "/qqqqq/ship/", "test/json/codeship_error.json", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#shipchannel1', '[\x0302manaplus/manaplus\x0f] Build for commit \x0303af76640\x0f from \x0303master\x0f failed https://app.codeship.com/projects/197019/builds/557e747d-2dc0-4898-ba1c-92a38e3af39b'),
                ('#shipchannel2', '[\x0302manaplus/manaplus\x0f] Build for commit \x0303af76640\x0f from \x0303master\x0f failed https://app.codeship.com/projects/197019/builds/557e747d-2dc0-4898-ba1c-92a38e3af39b')
            ])

    def test_post_codeship_build_error2(self):
        self.run_post("test/config/codeship2.yaml", "/qqqqq/ship/", "test/json/codeship_error.json", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#shipchannel1', '[\x0302manaplus/manaplus\x0f] Build for commit \x0303af76640\x0f from \x0303master\x0f failed https://app.codeship.com/projects/197019/builds/557e747d-2dc0-4898-ba1c-92a38e3af39b'),
                ('#shipchannel2', '[\x0302manaplus/manaplus\x0f] Build for commit \x0303af76640\x0f from \x0303master\x0f failed https://app.codeship.com/projects/197019/builds/557e747d-2dc0-4898-ba1c-92a38e3af39b')
            ])

    def test_post_codeship_build_error3(self):
        self.run_post("test/config/codeship3.yaml", "/qqqqq/ship/", "test/json/codeship_error.json", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_codeship_build_success1(self):
        self.run_post("test/config/codeship1.yaml", "/qqqqq/ship/", "test/json/codeship_success.json", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#shipchannel1', '[\x0302manaplus/manaplus\x0f] Build for commit \x030388e7212\x0f from \x0303master\x0f success https://app.codeship.com/projects/197019/builds/768925fd-bd65-499e-8078-49210a3e1e99'),
                ('#shipchannel2', '[\x0302manaplus/manaplus\x0f] Build for commit \x030388e7212\x0f from \x0303master\x0f success https://app.codeship.com/projects/197019/builds/768925fd-bd65-499e-8078-49210a3e1e99')
            ])

    def test_post_codeship_build_success2(self):
        self.run_post("test/config/codeship2.yaml", "/qqqqq/ship/", "test/json/codeship_success.json", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#shipchannel1', '[\x0302manaplus/manaplus\x0f] Build for commit \x030388e7212\x0f from \x0303master\x0f success https://app.codeship.com/projects/197019/builds/768925fd-bd65-499e-8078-49210a3e1e99'),
                ('#shipchannel2', '[\x0302manaplus/manaplus\x0f] Build for commit \x030388e7212\x0f from \x0303master\x0f success https://app.codeship.com/projects/197019/builds/768925fd-bd65-499e-8078-49210a3e1e99')
            ])

    def test_post_codeship_build_success3(self):
        self.run_post("test/config/codeship3.yaml", "/qqqqq/ship/", "test/json/codeship_success.json", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_codeship_build_waiting1(self):
        self.run_post("test/config/codeship1.yaml", "/qqqqq/ship/", "test/json/codeship_waiting.json", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_codeship_build_waiting2(self):
        self.run_post("test/config/codeship2.yaml", "/qqqqq/ship/", "test/json/codeship_waiting.json", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_codeship_build_waiting3(self):
        self.run_post("test/config/codeship3.yaml", "/qqqqq/ship/", "test/json/codeship_waiting.json", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_github_ping1(self):
        self.run_post_github("test/config/github_post1.yaml", "/qqqqq/", "test/json/github_ping.json", "ping", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_github_ping2(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_ping.json", "ping", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_github_status_pending1(self):
        self.run_post_github("test/config/github_post1.yaml", "/qqqqq/", "test/json/github_status_pending.json", "status", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_github_status_pending2(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_status_pending.json", "status", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_github_status_success1(self):
        self.run_post_github("test/config/github_post1.yaml", "/qqqqq/", "test/json/github_status_success.json", "status", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_github_status_success2(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_status_success.json", "status", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#channel1', '[\x0302ManaPlus\x0f] The Travis CI build passed for commit \x0303e2f8454\x0f from \x0303githubcitest\x0f https://travis-ci.org/ManaPlus/ManaPlus/builds/123456789'),
                ('#channel3', '[\x0302ManaPlus\x0f] The Travis CI build passed for commit \x0303e2f8454\x0f from \x0303githubcitest\x0f https://travis-ci.org/ManaPlus/ManaPlus/builds/123456789')
            ])

    def test_post_github_status_success3(self):
        self.run_post_github("test/config/github_post3.yaml", "/qqqqq/", "test/json/github_status_success.json", "status", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_github_status_failure1(self):
        self.run_post_github("test/config/github_post1.yaml", "/qqqqq/", "test/json/github_status_failure.json", "status", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_github_status_failure2(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_status_failure.json", "status", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#channel1', '[\x0302ManaPlus\x0f] The Travis CI build failed for commit \x030352c7786\x0f from \x0303githubcitest\x0f https://travis-ci.org/ManaPlus/ManaPlus/builds/123456789'),
                ('#channel3', '[\x0302ManaPlus\x0f] The Travis CI build failed for commit \x030352c7786\x0f from \x0303githubcitest\x0f https://travis-ci.org/ManaPlus/ManaPlus/builds/123456789'),
                ('#channel3', 'fail for channel 3')
            ])

    def test_post_github_status_failure3(self):
        self.run_post_github("test/config/github_post3.yaml", "/qqqqq/", "test/json/github_status_failure.json", "status", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_github_status_failure4(self):
        self.run_post_github("test/config/github_post4.yaml", "/qqqqq/", "test/json/github_status_failure.json", "status", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#channel1', '[\x0302ManaPlus\x0f] The Travis CI build failed for commit \x030352c7786\x0f from \x0303githubcitest\x0f https://travis-ci.org/ManaPlus/ManaPlus/builds/123456789'),
            ])

    def test_post_github_issues_opened(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_issues_opened.json", "issues", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#channel1', '[\x0302ManaPlus\x0f] \x0307issueuser\x0f opened issue \x0303#25\x0f: ManaPlus Client on the qqqq aa 3 ?   https://github.com/ManaPlus/ManaPlus/issues/25'),
                ('#channel2', '[\x0302ManaPlus\x0f] \x0307issueuser\x0f opened issue \x0303#25\x0f: ManaPlus Client on the qqqq aa 3 ?   https://github.com/ManaPlus/ManaPlus/issues/25')
            ])

    def test_post_github_issues_edited(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_issues_edited.json", "issues", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#channel1', '[\x0302ManaPlus\x0f] \x03074144\x0f edited issue \x0303#1\x0f: test issue header https://github.com/4144/ManaPlus/issues/1'),
                ('#channel2', '[\x0302ManaPlus\x0f] \x03074144\x0f edited issue \x0303#1\x0f: test issue header https://github.com/4144/ManaPlus/issues/1')
            ])

    def test_post_github_issues_closed(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_issues_closed.json", "issues", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#channel1', '[\x0302ManaPlus\x0f] \x03074144\x0f closed issue \x0303#1\x0f: test issue header https://github.com/4144/ManaPlus/issues/1'),
                ('#channel2', '[\x0302ManaPlus\x0f] \x03074144\x0f closed issue \x0303#1\x0f: test issue header https://github.com/4144/ManaPlus/issues/1')
            ])

    def test_post_github_issues_reopened(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_issues_reopened.json", "issues", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#channel1', '[\x0302ManaPlus\x0f] \x03074144\x0f reopened issue \x0303#1\x0f: test issue header https://github.com/4144/ManaPlus/issues/1'),
                ('#channel2', '[\x0302ManaPlus\x0f] \x03074144\x0f reopened issue \x0303#1\x0f: test issue header https://github.com/4144/ManaPlus/issues/1')
            ])

    def test_post_github_issue_comment_created(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_issue_comment_created.json", "issue_comment", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#channel2', '[\x0302ManaPlus\x0f] \x03074144\x0f add comment to issue \x0303#1\x0f: test issue header https://github.com/4144/ManaPlus/issues/1'),
                ('#channel3', '[\x0302ManaPlus\x0f] \x03074144\x0f add comment to issue \x0303#1\x0f: test issue header https://github.com/4144/ManaPlus/issues/1')
            ])

    def test_post_github_issue_comment_edited(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_issue_comment_edited.json", "issue_comment", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#channel2', '[\x0302ManaPlus\x0f] \x03074144\x0f edited comment in issue \x0303#1\x0f: test issue header https://github.com/4144/ManaPlus/issues/1'),
                ('#channel3', '[\x0302ManaPlus\x0f] \x03074144\x0f edited comment in issue \x0303#1\x0f: test issue header https://github.com/4144/ManaPlus/issues/1')
            ])

    def test_post_github_issue_comment_deleted(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_issue_comment_deleted.json", "issue_comment", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
            [
                ('#channel2', '[\x0302ManaPlus\x0f] \x03074144\x0f deleted comment from issue \x0303#1\x0f: test issue header https://github.com/4144/ManaPlus/issues/1'),
                ('#channel3', '[\x0302ManaPlus\x0f] \x03074144\x0f deleted comment from issue \x0303#1\x0f: test issue header https://github.com/4144/ManaPlus/issues/1')
            ])

    def test_post_github_check_suit_fail1(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_check_suite_failure.json", "check_suite", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_github_check_suit_fail2(self):
        self.run_post_github("test/config/github_post5.yaml", "/qqqqq/", "test/json/github_check_suite_failure.json", "check_suite", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
        [
            ('#channel1', '[\x0302ManaPlus\x0f] Azure Pipelines build failure for commit \x0303a22baa5\x0f from \x0303citest2\x0f https://github.com/ManaPlus/ManaPlus/commits/a22baa597ed605f1323507134adf4e19348b5cb6')
        ])

    def test_post_github_check_suit_success1(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_check_suite_success.json", "check_suite", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_github_check_suit_success2(self):
        self.run_post_github("test/config/github_post5.yaml", "/qqqqq/", "test/json/github_check_suite_success.json", "check_suite", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
        [
            ('#channel1', '[\x0302ManaPlus\x0f] Azure Pipelines build success for commit \x03031e25679\x0f from \x0303citest2\x0f https://github.com/ManaPlus/ManaPlus/commits/1e2567919c4b70ea9fa42e3f71dea2aec42a6f84')
        ])

    def test_post_github_check_suit_cancelled1(self):
        self.run_post_github("test/config/github_post2.yaml", "/qqqqq/", "test/json/github_check_suite_cancelled.json", "check_suite", 200)
        self.assertEqual(len(Core.messageHandler.messages), 0)

    def test_post_github_check_suit_cancelled2(self):
        self.run_post_github("test/config/github_post5.yaml", "/qqqqq/", "test/json/github_check_suite_cancelled.json", "check_suite", 200)
        self.assertEqual(sorted(Core.messageHandler.messages),
        [
            ('#channel1', '[\x0302ManaPlus\x0f] Azure Pipelines build cancelled for commit \x03037379863\x0f from \x0303citest2\x0f https://github.com/ManaPlus/ManaPlus/commits/7379863eb3babd6a3212c809c56134c7344f9cd3')
        ])


class TestLogger(unittest.TestCase):
    def setUp(self):
        Core.config = Configuration()
        Core.config.show_info = True
        Core.server = None
        Core.messageHandler = None
        Core.apiHandler = None
#        Core.log = logging.getLogger('log')

    def tearDown(self):
        Core.config = None
#        Core.log = None

    def test_addLog(self):
        Logger.addLog("test")

    def test_addError(self):
        Logger.addError("test")

print("----------------------------------------------------------------------")
#    suite = unittest.TestLoader().loadTestsFromTestCase(TestConfig)
#    unittest.TextTestRunner(verbosity = 2).run(suite)
if __name__ == '__main__':
    init_log()
    unittest.main(verbosity = 2)
#unittest.main()
